package plugin.validator;

import java.util.List;
import java.util.Map;

import org.pentaho.di.core.CheckResult;
import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.Counter;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.w3c.dom.Node;

public class PeselValidatorStepMeta extends BaseStepMeta implements
		StepMetaInterface {
	
	private static Class<?> PKG = PeselValidatorStepMeta.class; 

	// field which will be processed (verify)
	private String processedFieldName;

	// field storing data about PESEL correctness
	private String logicalFieldName;
	// field storing birth Date
	private String birthDateFieldName;
	// field storing sex
	private String sexFieldName;

	public PeselValidatorStepMeta() {
		super();
	}

	// processed column
	public void setProcessedFieldName(String processedFieldName) {
		this.processedFieldName = processedFieldName;
	}

	public String getProcessedFieldName() {
		return processedFieldName;
	}

	// logical field
	public void setLogicalFieldName(String logicalFieldName) {
		this.logicalFieldName = logicalFieldName;
	}

	public String getLogicalFieldName() {
		return logicalFieldName;
	}

	// birth date
	public void setBirthDateFieldName(String birthDateFieldName) {
		this.birthDateFieldName = birthDateFieldName;
	}

	public String getBirthDateFieldName() {
		return birthDateFieldName;
	}

	// sex field
	public void setSexFieldName(String sexFieldName) {
		this.sexFieldName = sexFieldName;
	}

	public String getSexFieldName() {
		return sexFieldName;
	}

	@Override
	public void setDefault() {
		logicalFieldName = "is correct";
		birthDateFieldName = "birth date";
		sexFieldName = "sex";
	}

	@Override
	public void getFields(RowMetaInterface inputRowMeta, String name,
			RowMetaInterface[] info, StepMeta nextStep, VariableSpace space)
			throws KettleStepException {

		String realProcessedFieldName = space
				.environmentSubstitute(processedFieldName);
		/*if (!Const.isEmpty(processedFieldName)) {
			ValueMetaInterface v = new ValueMeta(realProcessedFieldName,
					ValueMeta.TYPE_STRING);
			v.setOrigin(name);
			inputRowMeta.addValueMeta(v);
		}*/
		String realLogicalFieldName = space
				.environmentSubstitute(logicalFieldName);
		if (!Const.isEmpty(realLogicalFieldName)) {
			ValueMetaInterface v = new ValueMeta(logicalFieldName,
					ValueMeta.TYPE_STRING);
			v.setOrigin(name);
			inputRowMeta.addValueMeta(v);
		}
		String realBirthDateFieldName = space
				.environmentSubstitute(birthDateFieldName);
		if (!Const.isEmpty(birthDateFieldName)) {
			ValueMetaInterface v = new ValueMeta(realBirthDateFieldName,
					ValueMeta.TYPE_STRING);
			v.setOrigin(name);
			inputRowMeta.addValueMeta(v);
		}
		String realSexFieldName = space.environmentSubstitute(sexFieldName);
		if (!Const.isEmpty(sexFieldName)) {
			ValueMetaInterface v = new ValueMeta(realSexFieldName,
					ValueMeta.TYPE_STRING);
			v.setOrigin(name);
			inputRowMeta.addValueMeta(v);
		}
	}

	@Override
	public String getXML() throws KettleException {
		StringBuffer retval = new StringBuffer();

		retval.append("    "
				+ XMLHandler.addTagValue("processedFieldName",
						processedFieldName));
		retval.append("    "
				+ XMLHandler.addTagValue("logicalFieldName", logicalFieldName));
		retval.append("    "
				+ XMLHandler.addTagValue("birthDateFieldName",
						birthDateFieldName));
		retval.append("    "
				+ XMLHandler.addTagValue("sexFieldName", sexFieldName));

		return retval.toString();
	}

	@Override
	public void loadXML(Node stepnode, List<DatabaseMeta> databases,
			Map<String, Counter> counters) throws KettleXMLException {

		readData(stepnode);
	}

	private void readData(Node stepnode) throws KettleXMLException {
		try {
			processedFieldName = XMLHandler.getTagValue(stepnode,
					"processedFieldName"); //$NON-NLS-1$
			logicalFieldName = XMLHandler.getTagValue(stepnode,
					"logicalFieldName");
			birthDateFieldName = XMLHandler.getTagValue(stepnode,
					"birthDateFieldName");
			sexFieldName = XMLHandler.getTagValue(stepnode, "sexFieldName");

		} catch (Exception e) {
			throw new KettleXMLException("Unable to read data", e); //$NON-NLS-1$
		}
	}

	@Override
	public void saveRep(Repository rep, ObjectId id_transformation,
			ObjectId id_step) throws KettleException {
		rep.saveStepAttribute(id_transformation, id_step, "processedFieldName",
				processedFieldName);
		rep.saveStepAttribute(id_transformation, id_step, "logicalFieldName",
				logicalFieldName);
		rep.saveStepAttribute(id_transformation, id_step, "birthDateFieldName",
				birthDateFieldName);
		rep.saveStepAttribute(id_transformation, id_step, "sexFieldName",
				sexFieldName);
	}

	@Override
	public void readRep(Repository rep, ObjectId id_step,
			List<DatabaseMeta> databases, Map<String, Counter> counters)
			throws KettleException {
		try {
			processedFieldName = rep.getStepAttributeString(id_step,
					"processedFieldName");
			logicalFieldName = rep.getStepAttributeString(id_step,
					"logicalFieldName");
			birthDateFieldName = rep.getStepAttributeString(id_step,
					"birthDateFieldName");
			sexFieldName = rep.getStepAttributeString(id_step, "sexFieldName");

		} catch (Exception e) {
			throw new KettleException("UnexpectedErrorReadingStepInfo", e);
		}

	}

	@Override
	public void check(List<CheckResultInterface> remarks, TransMeta transMeta,
			StepMeta stepMeta, RowMetaInterface prev, String[] input,
			String[] output, RowMetaInterface info) {
		CheckResult cr;
		String error_message = "";

		String realProcessedFieldName = transMeta
				.environmentSubstitute(processedFieldName);
		if (Const.isEmpty(processedFieldName)) {
			error_message = "Validated field missing"; 
			cr = new CheckResult(CheckResult.TYPE_RESULT_ERROR, error_message,
					stepMeta);
			remarks.add(cr);
		} else {
			error_message = "Validated field ok"; 
			cr = new CheckResult(CheckResult.TYPE_RESULT_OK, error_message,
					stepMeta);
			remarks.add(cr);
		}
		// See if we have input streams leading to this step!
		if (input.length > 0) {
			cr = new CheckResult(
					CheckResult.TYPE_RESULT_OK,
					"CheckResult.ReceivingInfoFromOtherSteps", stepMeta); //$NON-NLS-1$
			remarks.add(cr);
		} else {
			cr = new CheckResult(
					CheckResult.TYPE_RESULT_ERROR,
					"CheckResult.NoInpuReceived", stepMeta); //$NON-NLS-1$
			remarks.add(cr);
		}

	}

	@Override
	public StepInterface getStep(StepMeta stepMeta,
			StepDataInterface stepDataInterface, int copyNr,
			TransMeta transMeta, Trans trans) {
		//TODO poprawic
		return new PeselValidatorStep(stepMeta, stepDataInterface, copyNr, transMeta, trans);
	}

	@Override
	public StepDataInterface getStepData() {
		// TODO poprawic
		return (StepDataInterface) new PeselValidatorStepData();
	}


	@Override
	public boolean supportsErrorHandling() {
		return true;
	}


	public Object clone() {
		PeselValidatorStepMeta retval = (PeselValidatorStepMeta) super.clone();
		return retval;
	}

}
